package com.forum.module.blog.controller.article;

import cn.hutool.core.collection.CollUtil;
import com.forum.framework.common.pojo.DataResult;
import com.forum.framework.common.pojo.PageResult;
import com.forum.framework.security.core.util.SecurityUtils;
import com.forum.module.blog.controller.article.vo.ArticlePageReqVO;
import com.forum.module.blog.controller.article.vo.ArticleRespVO;
import com.forum.module.blog.controller.article.vo.ArticleSaveReqVO;
import com.forum.module.blog.convert.article.ArticleConvert;
import com.forum.module.blog.convert.user.UserConvert;
import com.forum.module.blog.dal.dataobject.article.ArticleDO;
import com.forum.module.blog.dal.dataobject.article_tag.ArticleTagDO;
import com.forum.module.blog.dal.dataobject.category.CategoryDO;
import com.forum.module.blog.dal.dataobject.favorite.FavoriteDO;
import com.forum.module.blog.dal.dataobject.tag.TagDO;
import com.forum.module.blog.service.article.ArticleService;
import com.forum.module.blog.service.article_tag.ArticleTagService;
import com.forum.module.blog.service.category.CategoryService;
import com.forum.module.blog.service.favorite.FavoriteService;
import com.forum.module.blog.service.tag.TagService;
import com.forum.module.blog.service.user.UserService;
import com.forum.module.system.api.user.AdminUserApi;
import com.forum.module.system.api.user.dto.AdminUserRespDTO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.forum.framework.common.pojo.DataResult.success;

/**
 * 功能:
 * 作者:ouyzh
 * 日期:2025/3/2 18:37
 */
@Tag(name = "博客管理 - 文章")
@RestController
@RequestMapping("/blog/article")
public class ArticleController {
    private final ArticleService articleService;

    private final UserService userService;

    private final CategoryService categoryService;

    private final TagService tagService;

    private final ArticleTagService articleTagService;

    private final FavoriteService favoriteService;

    public ArticleController(ArticleService articleService,
                             UserService userService,
                             CategoryService categoryService,
                             TagService tagService,
                             ArticleTagService articleTagService,
                             FavoriteService favoriteService) {
        this.articleService = articleService;
        this.userService = userService;
        this.categoryService = categoryService;
        this.tagService = tagService;
        this.articleTagService = articleTagService;
        this.favoriteService = favoriteService;
    }

    @PostMapping("/create")
    @Operation(summary = "新增文章")
    public DataResult<Long> createArticle(@RequestBody ArticleSaveReqVO reqVO) {
        Long id = articleService.createArticle(reqVO);
        return success(id);
    }

    @PostMapping("/update")
    @Operation(summary = "更新文章")
    public DataResult<Boolean> updateArticle(@RequestBody ArticleSaveReqVO reqVO) {
        articleService.updateArticle(reqVO);
        return success(true);
    }

    @DeleteMapping("/delete")
    @Operation(summary = "删除文章信息")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public DataResult<Boolean> deleteArticle(@RequestParam("id") Long id) {
        articleService.deleteById(id);
        return success(true);
    }

//    @PutMapping("/update-status")
//    @Operation(summary = "修改文章状态")
//    public DataResult<Boolean> updateUserStatus(@Valid @RequestBody ArticleUpdateStatusReqVO reqVO) {
//        articleService.updateUserStatus(reqVO.getId(), reqVO.getStatus());
//        return success(true);
//    }

    @PostMapping("/page")
    @Operation(summary = "分页查询文章列表")
    public DataResult<PageResult<ArticleRespVO>> page(@RequestBody @Valid ArticlePageReqVO pageReqVO) {
        // 获得文章分页列表
        PageResult<ArticleDO> pageResult = articleService.getArticlePage(pageReqVO);

        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(new PageResult<>(pageResult.getTotal()));
        }

        List<ArticleRespVO> articleRespVOS = pageResult.getList().stream()
                .map(articleDO -> {
                    ArticleRespVO articleRespVO = handleBuildArticle(articleDO);
                    return articleRespVO;
                })
                .collect(Collectors.toList());

        return success(new PageResult<>(articleRespVOS, pageResult.getTotal()));
    }

    @PostMapping("/my-page")
    @Operation(summary = "分页查询草稿箱列表")
    public DataResult<PageResult<ArticleRespVO>> myPage(@RequestBody @Valid ArticlePageReqVO pageReqVO) {
        // 获得文章分页列表
        pageReqVO.setUserId(SecurityUtils.getLoginUserId());
        PageResult<ArticleDO> pageResult = articleService.getArticlePage(pageReqVO);

        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(new PageResult<>(pageResult.getTotal()));
        }

        List<ArticleRespVO> articleRespVOS = pageResult.getList().stream()
                .map(articleDO -> {
                    ArticleRespVO articleRespVO = handleBuildArticle(articleDO);
                    return articleRespVO;
                })
                .collect(Collectors.toList());

        return success(new PageResult<>(articleRespVOS, pageResult.getTotal()));
    }

    @GetMapping("/get")
    @Operation(summary = "获取文章信息详情")
    @Parameter(name = "id", description = "编号", required = true, example = "1024")
    public DataResult<ArticleRespVO> getArticle(@RequestParam("id") Long id) {
        ArticleDO article = articleService.getArticle(id);
        if (article == null) {
            return success(null);
        }

        ArticleRespVO articleRespVO = handleBuildArticle(article);
        return success(articleRespVO);
    }

    @PostMapping("/getFavoritePage")
    @Operation(summary = "获取收藏夹列表")
    public DataResult<PageResult<ArticleRespVO>> getFavoritePage(@RequestBody @Valid ArticlePageReqVO pageReqVO) {
        // 获得文章分页列表
        PageResult<ArticleDO> pageResult = articleService.getArticlePage(pageReqVO);

        Long loginUserId = SecurityUtils.getLoginUserId();
        List<FavoriteDO> favoriteDOS = favoriteService.getByUserId(loginUserId);

        Set<Long> favoriteIds = favoriteDOS.stream()
                .map(FavoriteDO::getArticleId)
                .collect(Collectors.toSet());

        if (CollUtil.isEmpty(pageResult.getList())) {
            return success(new PageResult<>(pageResult.getTotal()));
        }


        List<ArticleDO> favoriteArticles = pageResult.getList().stream()
                .filter(article -> favoriteIds.contains(article.getId()))
                .toList();

        List<ArticleRespVO> articleRespVOS = favoriteArticles.stream()
                .map(this::handleBuildArticle)
                .collect(Collectors.toList());


        return success(new PageResult<>(articleRespVOS, (long) articleRespVOS.size()));
    }

    private ArticleRespVO handleBuildArticle(ArticleDO article) {
        ArticleRespVO articleRespVO = ArticleConvert.INSTANCE.covert(article);
        articleRespVO.setUserInfo(UserConvert.INSTANCE.covert(userService.getById(article.getUserId())));

        Optional<CategoryDO> categoryDO = Optional.ofNullable(categoryService.getById(article.getCategoryId()));
        categoryDO.ifPresent(category -> articleRespVO.setCategoryName(category.getName()));

        // 获取文章标签信息
        List<TagDO> tags = tagService.list();
        Map<Long, String> tagNameMaps = tags.stream()
                .collect(Collectors.toMap(TagDO::getId, TagDO::getName));
        ArticleTagDO articleTag = articleTagService.getArticleTag(article.getId());
        if (articleTag != null) {
            articleRespVO.setTagName(tagNameMaps.get(articleTag.getTagId()));
        }

        // 获取每篇文章的收藏数
        List<FavoriteDO> favoriteDOS = favoriteService.list();
        Map<Long, Long> favoriteMaps = Optional.ofNullable(favoriteDOS)
                .orElse(Collections.emptyList())
                .stream()
                .filter(f -> f.getArticleId() != null)
                .collect(Collectors.groupingBy(
                        FavoriteDO::getArticleId,
                        Collectors.counting()
                ));

        articleRespVO.setFavorites(favoriteMaps.getOrDefault(article.getId(),0L));
        return articleRespVO;
    }
}
